
#include "dark-extermination.h"
#include "frametiming.h"
#include "textrenderer.h"
#include <string>

using namespace std;

DarkExtermination::DarkExtermination ()
{
	initialize();
	setupScene();
}

void DarkExtermination::setupScene()
{
	/** Creamos la escena */
	
	// Añadimos el cubo a la escena
	mySpaceship = new MySpaceship( "razor", "razor.mesh", sceneMgr );
	
	// 100 naves bastooooo
	Entity *ent;
	SceneNode *sceneNode;
	for(int i=0; i < 10; i++)
	{
		for(int j=0; j < 10; j++)
		{
			string s = "enemy" + i;
			s += j;
			ent = sceneMgr->createEntity( s, "razor.mesh" );
			ent->setCastShadows(false);
			sceneNode = sceneMgr->getRootSceneNode()->createChildSceneNode();
			sceneNode->setPosition(i*200, j*200, 0);
			sceneNode->attachObject(ent);
		}
	}
	
	// Creamos una vista que ocupe toda la ventana
	Viewport* vp = window->addViewport(mySpaceship->getCamera());
	vp->setBackgroundColour(ColourValue(0.5,0.5,0.5));
	mySpaceship->getCamera()->setAspectRatio(  Real(vp->getActualWidth()) / Real(vp->getActualHeight()) );

	// Create a skybox
	sceneMgr->setSkyBox(true, "SkyBox", 50 );
	
	// Add light
	Light *light;
	light = sceneMgr->createLight("Light3");
	light->setType(Light::LT_DIRECTIONAL);
	light->setDiffuseColour(ColourValue(1, 1, 1));
	light->setSpecularColour(ColourValue(1, 1, 1));
	light->setDirection(Vector3( -1, -1, 1 ));
	sceneMgr->getRootSceneNode()->attachObject( light );
}

void DarkExtermination::initialize()
{
	continue_or_not = true;
	
	/** Inicialización de Ogre */

	// Creamos el objeto principal
	root = new Root("plugins.cfg", "config.cfg", "pong3d.log");

	// Establecemos donde estarán los recursos (objetos y sus texturas, etc)
	ResourceGroupManager &resources=ResourceGroupManager::getSingleton();
	resources.addResourceLocation("data","FileSystem");
	resources.addResourceLocation("data/skybox.zip","Zip");
	resources.addResourceLocation("data/dani","FileSystem");
	
	// Cargamos todos los recursos
	resources.initialiseAllResourceGroups();

	// Leemos la configuración de config.cfg
	root->restoreConfig();
	// Aquí elegimos que el sistema cree una ventana  de renderizado por defecto al pasar la opción "true"
	window = root->initialise(true);
	
	//Register as a Window listener
	WindowEventUtilities::addWindowEventListener(window, this);

	// Creamos un manejador de escena genérico (podría haber sido de tipo octree, terrain, etc)
	sceneMgr = root->createSceneManager(ST_GENERIC, "Manejador de escena");
	sceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_ADDITIVE);
	sceneMgr->setAmbientLight(ColourValue(0, 0, 0));
	
	// Establecemos el nivel de mipmaping
	TextureManager::getSingleton().setDefaultNumMipmaps(5);
	
	new TextRenderer(); // hacer esto antes de crear el inputHandler
	
	inputHandler = new InputHandler(window);

}

int DarkExtermination::run()
{
	/** Bucle principal del juego */
	while (continue_or_not)
	{
		WindowEventUtilities::messagePump(); // Necesario en windows
		FrameTiming::getSingleton()->doFrameTiming();
		if(inputHandler != 0)
			inputHandler->capture();
		gameLogic();
		root->renderOneFrame(); // Renderizamos un frame
	}



	return 0;
}

DarkExtermination::~DarkExtermination()
{
	if(inputHandler != 0)
		delete inputHandler;
	
	exit(0);
}

void DarkExtermination::gameLogic()
{
	vector<Action> currentEvents = inputHandler->getCurrentEvents();
	
	mySpaceship->doActions(currentEvents);
	mySpaceship->doPhysics();
	
	for(vector<Action>::iterator it = currentEvents.begin(); it != currentEvents.end(); it++)
	{
// 		cout << "*it = " << *it << endl;
		switch (*it)
		{
			case  ACTION_NONE:
				break;
			case ACTION_SHUTDOWN:
				cout << "ACTION_SHUTDOWN" << endl;
				continue_or_not = false;
				break;
		}
	}
}

// WindowEventListener
void DarkExtermination::windowResized(RenderWindow* rw)
{
	unsigned int width, height, depth;
	int left, top;
	
	rw->getMetrics(width, height, depth, left, top);
	mySpaceship->getCamera()->setAspectRatio( Real(width) / height );
	if(inputHandler)
	inputHandler->setWindowExtents(width, height);
}

void DarkExtermination::windowClosed(RenderWindow* rw)
{
	if(rw == window)
	{
		delete inputHandler;
		inputHandler = 0;
		exit(0);
	}
}

